//
//  Engine.m
//  X2AX2B
//
//  Created by hotabbit on 14-8-2.
//  Copyright (c) 2014年 hotabbit. All rights reserved.
//


#import "Engine.h"
#import "Configuration.h"
#import "Agilent34410A.h"
#import "GWPower.h"
#import "JKSerialPort.h"

@interface Engine()
{
    NSNumber *ID;
    NSString *setVolt;
    NSString *getIndex;
    NSString *measBoardVolt1;
    NSString *dmmVolt1;
    NSString *getOffset;
    NSString *setOffset;
    NSString *measBoardVolt2;
    NSString *dmmVolt2;
    NSString *dValue;
    float differValue;
    int setRow;
    
    double everyVolt;
    
    Agilent34410A *agilentPower;
    JKSerialPort *serialPort;
    GWPower *gwPower;
    
    NSMutableArray* sendedCmdArray;
    
    NSCondition *condi;
    NSNotificationCenter *notification;
    NSMutableString *saveLog;
}

@end

@implementation Engine


-(instancetype)initWithObject:(TestView *)object
{
    if (self = [super init])
    {
        [self checkGPIBInstr];
        [self checkSerialPort];
        _testView = object;
        agilentPower = [[Agilent34410A alloc]init];
        serialPort = [[JKSerialPort alloc]initWithDevicePath:[Configuration instance].measureBoard
                                                 andBaudRate:115200 andDataBit:8 andStopBit:1 andParity:0];
        gwPower = [[GWPower alloc]init];
        
        condi = [[NSCondition alloc] init];
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(unLock) name:@"unlock" object:nil];
    

       }
    
    return self;
}

-(NSString *) checkSerialPort
{
    NSArray *array = [JKSerialPort portPaths];
    
    for (int i = 0; i < array.count; i++)
    {
        [Configuration instance].devices[i] = array[i];
    }
    
    return nil;
}

- (NSString *) checkGPIBInstr
{
    Agilent34410A *agilent = [[Agilent34410A alloc] init];
    GWPower *gwPower = [[GWPower alloc] init];
    if(![agilent Find])
    {
        return @"Cann't find the DMM!\nPlease check the connector";
    }
    
    if(![gwPower Find])
    {
        return @"Cann't find the Power!\nPlease check the connector";
    }
    return nil;
}

//弹窗警告退出
- (void) viewWaring:(NSString *)str
{
    NSAlert* alert = [[NSAlert alloc] init];
    [alert setMessageText:@"exception"];
    [alert setInformativeText:str];
    [alert runModal];
}


- (void)selectOpenDevice
{
    if (!gwPower.opened)
    {
        if (![gwPower OpenDevice])
        {
            [self viewWaring:@"Open GWPower error!!!"];
            [NSThread sleepForTimeInterval:3];
            return ;
        }
    }
    if(!agilentPower.opened)
    {
        if (![agilentPower OpenDevice])
        {
            [self viewWaring:@"Open Aglient34410 error!!!"];
            [NSThread sleepForTimeInterval:3];
            return ;
        }
    }
    
    serialPort = [[JKSerialPort alloc]initWithDevicePath:[Configuration instance].measureBoard
                                             andBaudRate:115200 andDataBit:8 andStopBit:1 andParity:0];

    if (![serialPort open])
        {
            [self viewWaring:@"Open SerailPort error!!!"];
            [NSThread sleepForTimeInterval:3];
            return ;
        }
    
    return;
}

//单项校准
- (void)singleStepExcute:(int)row
{
        float volt = row * everyVolt + [[Configuration instance].startVolt floatValue]/1000;
        setRow = row;
        NSMutableDictionary *dic = [self test:volt index:row+1];

        [self performSelectorOnMainThread:@selector(flushStepTest:) withObject:dic waitUntilDone:YES];
    
}

- (NSMutableDictionary *)test:(float)volt index:(int)index
{
    [gwPower sendCommand:@"*RST"];
    [gwPower sendCommand:@"*CLS"];
    [gwPower sendCommand:@"Output on"];
    [gwPower sendCommand:[NSString stringWithFormat:@"VOLT %f",volt/1000]];
    [gwPower sendCommand:@"MEAS:VOLT?"];
    //设置电压
    //setVolt = [gwPower readDataWithCountOfByte:1024];
    //float setvolt = [setVolt floatValue]*1000;
    [agilentPower sendCommand:@"*RST"];
    [agilentPower sendCommand:@"*CLS"];
    [agilentPower sendCommand:@":SENS:FUNC 'VOLT:DC'"];
    [agilentPower sendCommand:@":SENS:VOLT:DC:NPLC 0.02"];
    [agilentPower sendCommand:@":SENS:VOLT:DC:RANG 5"];
    //[agilentPower sendCommand:@":SYST:REM"];
    [agilentPower sendCommand:@"READ?"];
    
    //测量的标准电压
    dmmVolt1 = [agilentPower readDataWithCountOfByte:1024];
    
    
    //NSString *command1 = @"VM,1,1,1,16,1,200000,1";
    NSString *command1 = [NSString stringWithFormat:@"DCVM,0,1,%@,0,0,0,1,16,5,100000,1\r\n",[Configuration instance].chananel];
    
    [serialPort readExsiting];
    [serialPort writeString:command1];
    [NSThread sleepForTimeInterval:0.5];
    //第一次得到板子的测量值
    measBoardVolt1 = [serialPort readExsiting];
    NSString *measBoard = measBoardVolt1;
    NSRange range = [measBoardVolt1 rangeOfString:@"ADC:["];
    measBoardVolt1 = [measBoardVolt1 substringFromIndex:range.location+range.length];
    range = [measBoardVolt1 rangeOfString:@" mV]"];
    measBoardVolt1 = [measBoardVolt1 substringToIndex:range.location];
    
    NSRange range1 = [measBoard rangeOfString:@"Index="];
    measBoard = [measBoard substringFromIndex:range1.location +range1.length];
    range1 = [measBoard rangeOfString:@" ,GainFactor"];
    measBoard = [measBoard substringToIndex:range1.location];
    getIndex = measBoard;
    //[Configuration instance].measureVoltIndex = getIndex;
    //输入命令 得到原有的增益因数
    NSString *readOffset = [NSString stringWithFormat:@"EEREADADCAMPGAIN,1,%@\r\n",getIndex];
    [serialPort readExsiting];
    [serialPort writeString:readOffset];
    [NSThread sleepForTimeInterval:0.5];
    getOffset = [[serialPort readExsiting] stringByReplacingOccurrencesOfString:@"\r\n" withString:@""];
    
    float num1 = [measBoardVolt1 floatValue];
    float num2 = [dmmVolt1 floatValue];
    float num3 = [getOffset floatValue];
    dmmVolt1 = [NSString stringWithFormat:@"%lf",num2*1000];
    //计算得到新的增益因数,然后写入板子
    int temp = (num2 / num1 * num3)*1000;
    setOffset = [[NSString stringWithFormat:@"%d",temp] stringByReplacingOccurrencesOfString:@"," withString:@""];
    
    NSString *writeOffset = [NSString stringWithFormat:@"EEWRITEADCAMPGAIN,0,%@,%@\r\n",getIndex,setOffset];
    [serialPort readExsiting];
    [serialPort writeString:writeOffset];
    
    [agilentPower sendCommand:@"READ?"];
    dmmVolt2 = [agilentPower readDataWithCountOfByte:1024];
    
    NSString *command2 =[NSString stringWithFormat:@"DCVM,0,1,%@,0,0,0,1,16,5,100000,1\r\n",[Configuration instance].chananel];
    [NSThread sleepForTimeInterval:0.5];
    [serialPort readExsiting];
    [serialPort writeString:command2];
    [NSThread sleepForTimeInterval:0.5];
    //第二次得到板子的测量值
    measBoardVolt2 = [serialPort readExsiting];
    NSRange range3 = [measBoardVolt2 rangeOfString:@"ADC:["];
    if (range3.length > 0){
        measBoardVolt2 = [measBoardVolt2 substringFromIndex:range3.location+range3.length];
        range3 = [measBoardVolt2 rangeOfString:@" mV]"];
        measBoardVolt2 = [measBoardVolt2 substringToIndex:range3.location];
    }
    float num4 = [dmmVolt2 floatValue]*1000;
    dmmVolt2 = [NSString stringWithFormat:@"%lf",num4];
    float num5 = [measBoardVolt2 floatValue];
    
    //比较:是否在误差范围
    differValue = num5 - num4;
    dValue = [NSString stringWithFormat:@"%f",differValue];
    NSAttributedString* strTextdValue;
    if (fabs(differValue) > [[Configuration instance].measVoltTolerance doubleValue])
    {
        NSMutableDictionary *dic = [NSMutableDictionary dictionaryWithObjectsAndKeys:[NSColor redColor],NSForegroundColorAttributeName, nil];
        strTextdValue = [[NSAttributedString alloc] initWithString:dValue attributes:dic];
    }
    
    NSMutableDictionary* tableItem = [[NSMutableDictionary alloc] init];
    [tableItem setObject:[NSNumber numberWithInt:index] forKey:@"ID"];
    [tableItem setObject:[NSNumber numberWithFloat:volt] forKey:@"SetVolt"];
    [tableItem setObject:getIndex forKey:@"GetIndex"];
    [tableItem setObject:measBoardVolt1 forKey:@"MeasBoardVolt1"];
    [tableItem setObject:dmmVolt1 forKey:@"DMMVolt1"];
    [tableItem setObject:getOffset forKey:@"GetOffset"];
    [tableItem setObject:setOffset forKey:@"SetOffset"];
    [tableItem setObject:measBoardVolt2 forKey:@"MeasBoardVolt2"];
    [tableItem setObject:dmmVolt2 forKey:@"DMMVolt2"];
    [tableItem setObject:strTextdValue ? strTextdValue : dValue forKey:@"DValue"];
    
    
    if([[Configuration instance].save isEqual:@"1"])
    {
        NSMutableString *mutLog = [[NSMutableString alloc] init];
        [mutLog appendFormat:@"%i,%f,%@,%@,%@,%@,%i,%@,%@,%@\r\n",index,volt,getIndex,measBoardVolt1,dmmVolt1,getOffset,temp,measBoardVolt2,dmmVolt2,dValue];
        
        
        [self save:mutLog];
        
    }
    return tableItem;
}

//所有项测试执行
- (void)excuteAll
{
    //设置电压－－>验证
    //读出标准仪器电压－－>验证
    //校正－－>两者比较验证
    int index = 1;
    float volt = [[Configuration instance].startVolt floatValue];
    
    NSString *str = [self checkGPIBInstr];
    if (str != nil || [str isNotEqualTo:@""])
    {
        [self viewWaring:str];
        return;
    }
    
    [self selectOpenDevice];
     everyVolt = ([[Configuration instance].stopVolt floatValue] - [[Configuration instance].startVolt floatValue]) / ([[Configuration instance].stepCount floatValue] - 1);
    
    for (int i = 0;i < [[Configuration instance].stepCount intValue];i++)
    {
        volt = i == 0 ? volt : volt+everyVolt;
        NSMutableDictionary *tableItem = [self test:volt index:index];
         //[NSThread detachNewThreadSelector:@selector(flush:) toTarget:self withObject:tableItem];
        [self performSelectorOnMainThread:@selector(flush:) withObject:tableItem waitUntilDone:YES];
        index++;
        
        if ([[Configuration instance].stop isEqualToString:@"Stop"]) {
            [condi lock];
            [condi wait];
            [condi unlock];
        }
        
    }
    
}

-(void)unLock
{
    [condi lock];
    [condi signal];
    [condi unlock];
}

-(void)flush:(NSDictionary*)dic
{
    [_testView tableViewInit:dic];
}

-(void)flushStepTest:(NSDictionary*)dic
{
    [_testView tableViewInit:dic row:setRow];
}

- (void)save:(NSString *)msg
{
    NSString *dir = @"/vault/Data_Log";
    NSString *fname = @"/vault/Data_Log/log.csv";
    if(![[NSFileManager defaultManager] fileExistsAtPath:dir])
    {
        [[NSFileManager defaultManager] createDirectoryAtPath:dir withIntermediateDirectories:YES attributes:nil error:nil];
    }
    if(![[NSFileManager defaultManager] fileExistsAtPath:fname])
    {
        [[NSFileManager defaultManager] createFileAtPath:fname contents:nil attributes:nil];
        saveLog = [NSMutableString stringWithFormat:@"NO.,SET VOLT,GET INDEX,MeasBoard VOLT,DMM VOLT,GET OFFSET,SET OFFSET,MeasBoard VOLT,DMM VOLT,D-Value\r\n"];
        [saveLog writeToFile:fname atomically:YES encoding:NSUTF8StringEncoding error:nil];

    }
    NSFileHandle *fileHandle = [NSFileHandle fileHandleForUpdatingAtPath:fname];
    [fileHandle seekToEndOfFile];
    [fileHandle writeData:[msg dataUsingEncoding:NSUTF8StringEncoding]];
    [fileHandle closeFile];
}

- (void)setPowSupVoltage
{
    [self selectOpenDevice];
    [gwPower sendCommand:@"*RST"];
    [gwPower sendCommand:@"*CLS"];
    [gwPower sendCommand:@"Output on"];
    [gwPower sendCommand:[NSString stringWithFormat:@"VOLT %f",[[Configuration instance].setPowerSupVoltage floatValue] / 1000]];
    [gwPower sendCommand:@"MEAS:VOLT?"];
}

- (void)measBoardMeasVolt
{
    
    NSString *command = [NSString stringWithFormat:@"DCVM,0,1,%@,0,0,0,1,16,5,100000,1\r\n",[Configuration instance].chananel];
    
    [serialPort readExsiting];
    [serialPort writeString:command];
    [NSThread sleepForTimeInterval:0.5];
    //第一次得到板子的测量值
    NSString *measBoard = [serialPort readExsiting];
    //NSString *measBoard = measBoardVolt1;
    NSRange range = [measBoard rangeOfString:@"ADC:["];
    measBoard = [measBoard substringFromIndex:range.location+range.length];
    range = [measBoard rangeOfString:@" mV]"];
    
    [Configuration instance].measBoardMeasVolt = [measBoard substringToIndex:range.location];
    
    NSRange range1 = [measBoard rangeOfString:@"Index="];
    measBoard = [measBoard substringFromIndex:range1.location +range1.length];
    range1 = [measBoard rangeOfString:@" ,GainFactor"];
    measBoard = [measBoard substringToIndex:range1.location];
    getIndex = measBoard;
    [Configuration instance].measureVoltIndex = getIndex;
    //输入命令 得到原有的增益因数
}

- (void)dmmMeasVolt
{
    [agilentPower sendCommand:@"*RST"];
    [agilentPower sendCommand:@"*CLS"];
    [agilentPower sendCommand:@":SENS:FUNC 'VOLT:DC'"];
    [agilentPower sendCommand:@":SENS:VOLT:DC:NPLC 0.02"];
    [agilentPower sendCommand:@":SENS:VOLT:DC:RANG 5"];
    //[agilentPower sendCommand:@":SYST:REM"];
    [agilentPower sendCommand:@"READ?"];
    
    //测量的标准电压
    [Configuration instance].dmmMeasVolt = [agilentPower readDataWithCountOfByte:1024];
}

- (void)getReadVoltOffset
{
    
    NSString *readOffset = [NSString stringWithFormat:@"EEREADADCAMPGAIN,1,%@\r\n",[Configuration instance].measureVoltIndex];
    [serialPort readExsiting];
    [serialPort writeString:readOffset];
    [NSThread sleepForTimeInterval:0.5];
    [Configuration instance].getReadVoltOffset = [serialPort readExsiting];
    
}

- (void)setReadVoltOffset
{
    NSString *writeOffset = [NSString stringWithFormat:@"EEWRITEADCAMPGAIN,0,%@,%@\r\n",[Configuration instance].measureVoltIndex,[Configuration instance].setReadVoltOffset];
    [serialPort readExsiting];
    [serialPort writeString:writeOffset];
    
}

@end
